﻿using System;

namespace Chess.Domain
{
	/// <summary>
	/// Defines one square of the chess board.
	/// </summary>
	public class Position
	{
		#region " Constructor "

		/// <summary>
		/// 
		/// </summary>
		/// <remarks>
		/// Use internal modifier, to not allow creation without
		/// necessary parameters.
		/// </remarks>
		internal Position()
		{

		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		public Position(Rank rank, File file)
		{
			this.Rank = rank;
			this.File = file;
		}

		#endregion

        #region " Properties "

        private Rank _Rank;

        /// <summary>
        /// 
        /// </summary>
        public Rank Rank
        {
            get { return _Rank; }
            set { _Rank = value; }
        }

        private File _File;

        /// <summary>
        /// 
        /// </summary>
        public File File
        {
            get { return _File; }
            set { _File = value; }
        } 

        #endregion


        /// <summary>
        /// 
        /// </summary>
        /// <param name="changeInRank"></param>
        /// <param name="changeInFile"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public bool CanTranslate(int deltaY, int deltaX, out Position position)
        {
            bool result = true;
            position = null;

			int y = (int)this.Rank + deltaY;
			int x = (int)this.File + deltaX;

			result &= y >= 0;
			result &= y <= 7;
			result &= x >= 0;
			result &= x <= 7;

			if (result)
			{
				position = new Position((Rank)y, (File)x);
			}

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            bool result = true;

            Position objAsPosition = obj as Position;

            if (objAsPosition == null)
            {
                throw new ArgumentException();
            }
            else
            {
                result &= this.File == objAsPosition.File;
                result &= this.Rank == objAsPosition.Rank;
            }

            return result;
        }

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			return string.Format("Chess.Domain.Position: Rank={0} File={1}", Rank, File);
		}
	}
}
